#include "ClientHandler.h"

ClientHandler::ClientHandler(QWebSocket* socket,const QString& id,QObject *parent)
    :QObject{parent},m_socket(socket),m_id(id)
{
    // 使用qobject_cast安全地将parent转换为Server*类型并保存
    m_server = qobject_cast<Server*>(parent);
    if (!m_server) {
        qWarning() << "将parent转换为Server*类型的操作失败";
    }
    // 获取一个自身的数据库连接
    m_db = m_server->getDBConnection();

    // 信号槽的连接
    connect(m_socket,&QWebSocket::disconnected,this,&ClientHandler::onDisconnected);
    connect(m_socket,&QWebSocket::textMessageReceived,this,&ClientHandler::onTextMessageReceived);

    qDebug()<<"我是新链接的用户，目前账号的默认的"<<m_id;
}

void ClientHandler::sendJsonToClient(QJsonObject &jsonObj)
{
    jsonObj["end"] = "end";
    QJsonDocument jsonDoc(jsonObj);
    QByteArray jsonData = jsonDoc.toJson();
    QString jsonStr = QString::fromUtf8(jsonData);
    m_socket->sendTextMessage(jsonStr);
    m_socket->flush();
}

void ClientHandler::sendFriendInfoToClient(QString id)
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "newFriendInfo";

    QSqlQuery query(m_db);
    query.prepare("select * from Users where id = :id");
    query.bindValue(":id",id);
    if(!query.exec() || !query.next()){
        qDebug()<<"服务端查询新好友的信息的sql语句执行失败"<<query.lastError();
        return;
    }

    // 打包数据
    jsonObj["id"] = query.value("id").toString();
    jsonObj["nickname"] = query.value("nickname").toString();
    jsonObj["gender"] = query.value("gender").toString();
    jsonObj["signature"] = query.value("signature").toString();
    jsonObj["avatar"] = query.value("avatar").toString();
    sendJsonToClient(jsonObj);
}

void ClientHandler::dealRegister(const QJsonObject &jsonObj)
{
    qDebug()<<"服务端成功收到客户端发来的注册请求";
    QJsonObject jsonObjR;
    jsonObjR["tag"] = "register";

    // 生成一个唯一的id (12位)
    qint64 idNum = QRandomGenerator::global()->bounded(100000000000, 1000000000000);

    // 判断是否已经在数据库中存在
    QSqlQuery query(m_db);
    query.prepare("select count(*) from Users where id = :id");
    query.bindValue(":id",QString::number(idNum));
    // 循环判断是否发生重复
    while(query.exec() && query.next()){
        if(query.value(0).toInt() != 0){// 说明重复了
            idNum = QRandomGenerator::global()->bounded(100000000000, 1000000000000);
            continue;
        }
        break;
    }

    if(!query.isActive()){
        qDebug()<<"服务端生成唯一id的sql语句执行失败"<<query.lastError();
        jsonObjR["reply"] = "faild";
        sendJsonToClient(jsonObjR);
        return;
    }

    // 到这里成功生成了唯一的id，将其存入数据库
    query.prepare("insert into Users(id,pwd,nickname,signature,gender,avatar,question,answer) "
                  "values(:id,:pwd,:nickname,'一行代码三个报错',:gender,:avatar,:question,:answer)");
    query.bindValue(":id",QString::number(idNum));
    query.bindValue(":pwd",jsonObj["pwd"].toString());
    query.bindValue(":nickname",jsonObj["nickname"].toString());
    query.bindValue(":gender",jsonObj["gender"].toString());
    query.bindValue(":avatar",jsonObj["avatar"].toString());
    query.bindValue(":question",jsonObj["safeQ"].toString());
    query.bindValue(":answer",jsonObj["safeA"].toString());
    if(!query.exec()){
        qDebug()<<"服务端插入新注册的用户的sql语句执行失败"<<query.lastError();
        jsonObjR["reply"] = "faild";
        sendJsonToClient(jsonObjR);
        return;
    }

    // 通知客户端注册成功
    jsonObjR["reply"] = "succeed";
    jsonObjR["id"] = QString::number(idNum);
    jsonObjR["pwd"] = jsonObj["pwd"].toString();
    sendJsonToClient(jsonObjR);
}

void ClientHandler::dealLogin(const QJsonObject &jsonObj)
{
    QJsonObject jsonObjR;
    jsonObjR["tag"] = "login";

    // 检查是否已经登陆
    ClientHandler* c = m_server->getClientHandlerByAccount(jsonObj["id"].toString());
    if(c != nullptr){
        jsonObjR["reply"] = "faild";
        jsonObjR["note"] = "repeatLogin";// 备注
        sendJsonToClient(jsonObjR);
        return;// 已经登陆了就直接返回
    }

    // 检查账号和密码是否对得上
    QSqlQuery query(m_db);
    query.prepare("select count(*) from Users where id = :id and pwd = :pwd");
    query.bindValue(":id",jsonObj["id"].toString());
    query.bindValue(":pwd",jsonObj["pwd"].toString());
    if(!query.exec()){
        qDebug()<<"服务端处理登录时检查账号密码是否正确的sql语句执行失败"<<query.lastError();
        jsonObjR["reply"] = "faild";
        sendJsonToClient(jsonObjR);
        return;
    }

    if(query.next() && query.value(0).toInt() == 1){
        // 有记录说明账号和密码是正确的
        m_id = jsonObj["id"].toString();
        m_server->addClientToHash(m_id, this);

        // 通知客户端登录成功
        jsonObjR["reply"] = "succeed";
        jsonObjR["id"] = m_id;
        sendJsonToClient(jsonObjR);
        return;
    }
    else{// 账号或密码错误
        jsonObjR["reply"] = "faild";
        sendJsonToClient(jsonObjR);
        return;
    }


    m_server->addClientToHash(m_id,this);
}

void ClientHandler::dealFindPwdStep2(const QString &id, const QString &safeA)
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "findPwdStep2";

    // 验证答案是否正确
    QSqlQuery query(m_db);
    query.prepare("select count(*) from Users where id = :id and answer = :answer");
    query.bindValue(":id",id);
    query.bindValue(":answer",safeA);
    if(!query.exec() || !query.next()){
        qDebug()<<"服务端处理找回密码第二步的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
        return;
    }

    if(query.value(0).toInt() == 1){
        jsonObj["reply"] = "succeed";
    }
    else{
        jsonObj["reply"] = "faild";
    }
    sendJsonToClient(jsonObj);
}

void ClientHandler::dealFindPwdStep3(const QString &id, const QString &pwd)
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "findPwdStep3";
    // 更新密码
    QSqlQuery query(m_db);
    query.prepare("update Users set pwd = :pwd where id = :id");
    query.bindValue(":pwd",pwd);
    query.bindValue(":id",id);
    if(!query.exec()){
        jsonObj["reply"] = "faild";
        return;
    }else{
        jsonObj["reply"] = "succeed";
    }

    sendJsonToClient(jsonObj);
}

void ClientHandler::dealDeleteAccount()
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "deleteAccount";

    if(!m_db.transaction()){
        qDebug()<<"删除自己的账号的数据库事务开启失败"<<m_db.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
    }

    // 在Users表中删除自己的数据
    QSqlQuery query(m_db);
    query.prepare("delete from Users where id = :id");
    query.bindValue(":id", m_id);
    if(!query.exec()){
        qDebug()<<"删除账号逻辑汇总从Users表移除自己的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
    }

    // 在Friends表中删除相关的数据
    query.prepare("delete from Friends where user_id = :id or friend_id = :id");
    query.bindValue(":id", m_id);
    if(!query.exec()){
        qDebug()<<"删除账号逻辑汇总从Friend表移除自己的sql语句执行失败"<<query.lastError();
        m_db.rollback();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
    }

    m_db.commit();// 删除了User表和Friend表的数据已经说明删除成功了


    // 在Messages表中删除相关的数据
    query.prepare("delete from Messages where sender_id = :id or receiver_id = :id");
    query.bindValue(":id", m_id);
    if(!query.exec()){
        qDebug()<<"删除账号逻辑汇总从Messages移除数据的sql语句执行失败（脏数据）"<<query.lastError();
    }

    jsonObj["reply"] = "succeed";
    sendJsonToClient(jsonObj);

    // 延迟100毫秒保证有时间通知客户端
    QTimer::singleShot(100,[=](){
        m_server->removeClientToHash(m_id);
        m_server->releaseDBConnection(m_db);
    });
}

void ClientHandler::dealMyInfo()
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "myInfo";

    // 查询个人资料
    QSqlQuery query(m_db);
    query.prepare("select * from Users where id = :id");
    query.bindValue(":id",m_id);
    if(!query.exec() || !query.next()){
        qDebug()<<"发送自身信息给客户端的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
        return;
    }

    // 打包数据
    jsonObj["id"] = m_id;
    jsonObj["pwd"] = query.value("pwd").toString();
    jsonObj["nickname"] = query.value("nickname").toString();
    jsonObj["signature"] = query.value("signature").toString();
    jsonObj["avatar"] = query.value("avatar").toString();
    jsonObj["gender"] = query.value("gender").toString();
    jsonObj["question"] = query.value("question").toString();
    jsonObj["answer"] = query.value("answer").toString();
    jsonObj["reply"] = "succeed";
    sendJsonToClient(jsonObj);
}

void ClientHandler::dealFriendInfo()
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "friendInfo";

    // 查询好友资料
    QSqlQuery query(m_db);
    query.prepare("select friend_id from Friends where user_id = :id");
    query.bindValue(":id",m_id);
    if(!query.exec()){
        qDebug()<<"查询自身所有好友的id的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
        return;
    }

    QList<QString> friendIdList;
    while (query.next()) {
        friendIdList.append(query.value(0).toString());
    }

    // 遍历容器，重复查找
    QJsonArray jsonArray;
    query.prepare("select id,nickname,signature,gender,avatar from Users where id = :id");
    for(const QString& id : friendIdList){
        query.bindValue(":id",id);// 每次循环更新绑定的id值
        if(query.exec() && query.next()){
            QJsonObject js;
            js["id"] = query.value(0).toString();
            js["nickname"] = query.value(1).toString();
            js["signature"] = query.value(2).toString();
            js["gender"] = query.value(3).toString();
            js["avatar"] = query.value(4).toString();
            jsonArray.append(js);
        }
    }
    jsonObj["array"] = jsonArray;
    jsonObj["reply"] = "succeed";
    sendJsonToClient(jsonObj);
}

void ClientHandler::dealFriendRequestList()
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "friendRequestList";

    QSqlQuery query(m_db);
    query.prepare("select sender_id from FriendRequests where sender_id = :id and status = 'pending'");
    query.bindValue(":id",m_id);
    if(!query.exec()){
        qDebug()<<"服务器查找好友申请列表的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
        return;
    }

    QList<QString> list;
    while (query.next()) {
        list.append(query.value(0).toString());
    }

    // 查询所有的需要的信息（头像、昵称，账号）
    QJsonArray array;
    query.prepare("select id,nickname,avatar from Users where id = :id");
    for(const QString& id : list){
        query.bindValue(":id",id);
        if(query.exec() && query.next()){
            QJsonObject js;
            js["id"] = query.value(0).toString();
            js["nickname"] = query.value(1).toString();
            js["avatar"] = query.value(2).toString();
            array.append(js);
        }
    }

    jsonObj["array"] = array;
    jsonObj["reply"] = "succeed";
    sendJsonToClient(jsonObj);
}

void ClientHandler::dealMyUnReadMsg()
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "myUnReadMsg";

    QSqlQuery query(m_db);
    query.prepare("select sender_id, content, filename, message_type from Messages where status = 'unRead' order by timestamp ASC");
    if(!query.exec()){
        qDebug()<<"服务端初始时查找所有未读消息的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
        return;
    }

    QJsonArray jsonArray;

    while (query.next()) {
        QJsonObject js;
        js["friend_id"] = query.value("sender_id").toString();
        js["content"] = query.value("content").toString();
        js["filename"] = query.value("filename").toString();
        js["message_type"] = query.value("message_type").toString();
        jsonArray.append(js);
    }

    jsonObj["array"] = jsonArray;
    jsonObj["reply"] = "succeed";
    sendJsonToClient(jsonObj);

    // 将所有消息设置为已读
    query.prepare("update Messages set status = 'read' where status = 'unRead'");
    if(!query.exec()){
        qDebug()<<"服务端在发送完未读消息，将其变为已读的sql语句执行失败（脏数据）"<<query.lastError();
    }
}

void ClientHandler::dealOutOfLogin()
{
    // 将自己从哈希表中删除，避免影响下一次登录
    m_server->removeClientToHash(m_id);
    m_server->releaseDBConnection(m_db);// 释放自己的下一次连接
}

void ClientHandler::dealSearchFriendInfo(QString id)
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "searchFriendInfo";

    QSqlQuery query(m_db);
    query.prepare("select * from Users where id = :id");
    query.bindValue(":id",id);
    if(!query.exec() || !query.next()){
        qDebug()<<"服务端查询某个人的信息的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
    }

    // 打包数据
    jsonObj["id"] = query.value("id").toString();
    jsonObj["nickname"] = query.value("nickname").toString();
    jsonObj["gender"] = query.value("gender").toString();
    jsonObj["signature"] = query.value("signature").toString();
    jsonObj["avatar"] = query.value("avatar").toString();
    jsonObj["reply"] = "succeed";
    sendJsonToClient(jsonObj);
}

void ClientHandler::dealAddFriendRequest(QString id)
{

    // pending、accepted、rejected
    // 检查这名好友是否在线，在线则直接发给它，否则先存到数据库，等它上线后再加
    QSqlQuery query(m_db);
    query.prepare("insert into FriendRequests(sender_id, receiver_id, status, timestamp) values(:sender_id, :receiver_id, 'pending', :timestamp)");
    query.bindValue(":sender_id", m_id);
    query.bindValue(":receiver_id",id);
    QDateTime curTime = QDateTime::currentDateTimeUtc();
    QString timestamp = curTime.toString("yyyy-MM-dd HH-mm-ss");
    query.bindValue(":timestamp",timestamp);
    if(!query.exec()){
        qDebug()<<"服务端插入好友申请请求的sql语句执行失败"<<query.lastError();
        return;
    }

    ClientHandler* f = m_server->getClientHandlerByAccount(id);
    if(f != nullptr){
        // 说明当前这个好友在线，需要直接发送给好友（附上我的头像和昵称信息）
        query.prepare("select nickname,avatar from Users where id = :id");
        query.bindValue(":id",m_id);
        if(!query.exec() || !query.next()){
            qDebug()<<"将好友申请发送给在线的对方的sql语句执行失败"<<query.lastError();
            return;
        }
        QJsonObject jsonObj;
        jsonObj["tag"] = "addFriendRequest";
        jsonObj["id"] = m_id;
        jsonObj["nickname"] = query.value("nickname").toString();
        jsonObj["avatar"] = query.value("avatar").toString();

        // QueuedConnection可以确保信号对应的槽函数被执行，避免直接断开后信号发布出去
        connect(this,&ClientHandler::friendRequest,f,&ClientHandler::onFriendRequest, Qt::QueuedConnection);
        emit friendRequest(jsonObj);
        disconnect(this,&ClientHandler::friendRequest,f,&ClientHandler::onFriendRequest);
    }
}

void ClientHandler::dealAddFriendAnswer(const QJsonObject &jsonObj)
{
    QString friend_id = jsonObj["id"].toString();
    QSqlQuery query(m_db);
    query.prepare("update FriendRequests set status = :status where sender_id = :sender_id and receiver_id = :receiver_id");
    query.bindValue(":sender_id", friend_id);
    query.bindValue(":receiver_id",m_id);
    if(!m_db.transaction()){
        qDebug()<<"对好友申请回复进行处理的逻辑的数据库事务开启失败"<<m_db.lastError();
        return;
    }

    if(jsonObj["reply"].toString() == "reject"){
        // 更改申请表中的状态
        query.bindValue(":status", "rejected");
        if(!query.exec()){
            qDebug()<<"更改申请表中申请条目的状态的sql语句执行失败"<<query.lastError();
        }
        m_db.commit();
        return;// 被拒绝了
    }
    else if(jsonObj["reply"].toString() == "accept"){
        // 在数据库的friend表插入数据，并更改申请表中的状态
        query.bindValue(":status", "accepted");
        if(!query.exec()){
            qDebug()<<"更改申请表中申请条目的状态的sql语句执行失败"<<query.lastError();
        }

        query.prepare("insert into Friends(user_id,friend_id) values(:user_id,:friend_id)");
        query.bindValue(":user_id",m_id);
        query.bindValue(":friend_id",friend_id);
        if(!query.exec()){
            qDebug()<<"往好友表中插入数据的sql语句执行失败"<<query.lastError();
            m_db.rollback();
            return;
        }

        query.bindValue(":friend_id",m_id);
        query.bindValue(":user_id",friend_id);
        if(!query.exec()){
            qDebug()<<"往好友表中插入数据的sql语句执行失败"<<query.lastError();
            m_db.rollback();
            return;
        }
        m_db.commit();

        // 向对方发信号，说我已经是你的好友了
        ClientHandler* f = m_server->getClientHandlerByAccount(friend_id);
        // 最后一个参数保证槽函数会被执行
        connect(this,&ClientHandler::iamNewFriend,f,&ClientHandler::onIamNewFriend,Qt::QueuedConnection);
        emit iamNewFriend(m_id);
        disconnect(this,&ClientHandler::iamNewFriend,f,&ClientHandler::onIamNewFriend);

        // 向自己的客户端发送对方的信息
        sendFriendInfoToClient(friend_id);
    }
}

void ClientHandler::dealDeleteAFriend(QString id)
{
    // 删除服务器中数据库的数据
    QSqlQuery query(m_db);
    query.prepare("delete from Friends where user_id = :user_id and friend_id = :friend_id");
    query.bindValue(":user_id", id);
    query.bindValue(":friend_id",m_id);
    if(!query.exec()){
        qDebug()<<"删除好友"<<id<<", "<<m_id<<"逻辑的sql语句执行失败(脏数据)"<<query.lastError();
    }

    query.bindValue(":user_id", m_id);
    query.bindValue(":friend_id",id);
    if(!query.exec()){
        qDebug()<<"删除好友"<<m_id<<", "<<id<<"逻辑的sql语句执行失败(脏数据)"<<query.lastError();
    }

    // 通知对方，你已经被我删除了
    ClientHandler* c = m_server->getClientHandlerByAccount(id);
    connect(this,&ClientHandler::youAreDelete,c,&ClientHandler::onYouAreDelete,Qt::QueuedConnection);
    emit youAreDelete(m_id);
    disconnect(this,&ClientHandler::youAreDelete,c,&ClientHandler::onYouAreDelete);
}

void ClientHandler::dealMsg(const QJsonObject &jsonObj)
{
    QString receiver = jsonObj["receiver"].toString();
    QString text = jsonObj["text"].toString();
    QString status = "unRead";
    QString timestamp = QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd HH:mm:ss");
    QString msgType = jsonObj["type"].toString();// textType/fileType/photoType
    QString filename = jsonObj["filename"].toString();

    // 先判断这个人是否在线
    ClientHandler* c = m_server->getClientHandlerByAccount(receiver);
    if(c != nullptr){
        status = "read";
        // 将这条信息转发给对应的客户端（直接调用对方的函数，而不使用信号槽机制,避免频繁连接和断开）
        c->receiveANewMsg(m_id ,msgType, text, filename);
    }

    // 将这条信息存入数据库
    QSqlQuery query(m_db);

    // 判断这个人是否已经注销账号了
    query.prepare("select count(*) from Users where id = :id");
    query.bindValue(":id", receiver);
    if(query.exec() && query.next() && query.value(0).toInt() == 0){
        QJsonObject jsonObj;
        jsonObj["tag"] = "friend_cancel";
        jsonObj["friend_id"] = receiver;
        sendJsonToClient(jsonObj);

        return;// 找不到这个人就不写入记录
    }

    query.prepare("insert into Messages(sender_id,receiver_id,content,filename,status,timestamp,message_type) values(:sender_id,:receiver_id,:content,:filename,:status,:timestamp,:message_type)");
    query.bindValue(":sender_id", m_id);
    query.bindValue(":receiver_id", receiver);
    query.bindValue(":content", text);
    query.bindValue(":filename",filename);
    query.bindValue(":status", status);
    query.bindValue(":timestamp", timestamp);
    query.bindValue(":message_type", msgType);
    if(!query.exec()){
        qDebug()<<"服务端尝试将一条由"<<m_id<<"发送给"<<receiver<<"的信息："<<text<<"保存到数据库中失败"<<query.lastError();
    }
}

void ClientHandler::dealUpdateMyInfo(const QJsonObject &jsonObj)
{
    QJsonObject json;
    json["tag"] = "updateMyInfo";

    QString pwd = jsonObj["pwd"].toString();
    QString nickname = jsonObj["nickname"].toString();
    QString gender = jsonObj["gender"].toString();
    QString signature = jsonObj["signature"].toString();
    QString question = jsonObj["question"].toString();
    QString answer = jsonObj["answer"].toString();
    QString avatarStr = jsonObj["avatar"].toString();

    // 将新的信息写入数据库
    QSqlQuery query(m_db);
    query.prepare("update Users set pwd=:pwd,nickname=:nickname,signature=:signature,gender=:gender,avatar=:avatar, question=:question, answer=:answer where id = :id");
    query.bindValue(":pwd", pwd);
    query.bindValue(":nickname", nickname);
    query.bindValue(":signature", signature);
    query.bindValue(":gender", gender);
    query.bindValue(":avatar", avatarStr);
    query.bindValue(":question", question);
    query.bindValue(":answer", answer);
    query.bindValue(":id", m_id);
    if(!query.exec()){
        qDebug()<<"更改我的个人信息的sql语句执行失败"<<query.lastError();
        json["reply"] = "faild";
        sendJsonToClient(json);
        return;
    }

    // 通知其他在线的好友，我的信息更改了（不在线的上线后已经是最新的了）
    query.prepare("select friend_id from Friends where user_id = :id");
    query.bindValue(":id", m_id);
    if(!query.exec()){
        qDebug()<<"服务端通知我的好友，我的个人信息已经修改的sql语句执行失败"<<query.lastError();
    }else{
        while (query.next()) {
            QString friend_id = query.value(0).toString();
            ClientHandler* c = m_server->getClientHandlerByAccount(friend_id);
            if(c){// 有就说明在线
                connect(this,&ClientHandler::friendChangeInfo, c,&ClientHandler::onFriendChangeInfo,Qt::QueuedConnection);
                emit friendChangeInfo(m_id);
                disconnect(this,&ClientHandler::friendChangeInfo, c,&ClientHandler::onFriendChangeInfo);
            }
        }
    }

    json["reply"] = "succeed";
    sendJsonToClient(json);
}

void ClientHandler::onFriendRequest(QJsonObject& jsonObj)
{
    // 将请求发送给客户端
    sendJsonToClient(jsonObj);
}

void ClientHandler::onIamNewFriend(QString id)
{
    // 向自己的客户端发送新朋友的信息
    sendFriendInfoToClient(id);
}

void ClientHandler::dealFindPwdStep1(const QString& id)
{
    QJsonObject jsonObj;
    jsonObj["tag"] = "findPwdStep1";

    // 1.检查这个账号是否存在（有效）
    QSqlQuery query(m_db);
    query.prepare("select question from Users where id = :id");
    query.bindValue(":id",id);
    if(!query.exec() || !query.next()){
        qDebug()<<"服务端找回密码第一步的sql语句执行失败"<<query.lastError();
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
        return;
    }

    QString safeQ = query.value(0).toString();
    if(safeQ.isEmpty()){
        jsonObj["reply"] = "faild";
        sendJsonToClient(jsonObj);
    }
    // 2.发送对应的密保问题
    else{
        jsonObj["reply"] = "succeed";
        jsonObj["safeQ"] = safeQ;
        sendJsonToClient(jsonObj);
    }
}

void ClientHandler::onDisconnected()
{
    qDebug()<<"客户端"<<m_id<<"主动断开连接";
    m_server->removeClientToHash(m_id);
    m_server->releaseDBConnection(m_db);
}

void ClientHandler::onTextMessageReceived(const QString &message)
{
    // 检查收到的数据是不是json格式
    QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8());
    if(!jsonDoc.isObject()){
        qDebug()<<"客户端收到一条非法数据";
        return;
    }

    // 转为json对象
    QJsonObject jsonObj = jsonDoc.object();
    if(jsonObj["end"] != "end"){
        qDebug()<<"客户端收到一条没有结束标志的非法数据";
        return;
    }

    //根据json["tag"]标签进行分类处理
    QString tag = jsonObj["tag"].toString();

    if(tag == "register"){
        dealRegister(jsonObj);
    }
    else if(tag == "login"){
        dealLogin(jsonObj);
    }
    else if(tag == "msg"){
        dealMsg(jsonObj);
    }
    else if(tag == "findPwdStep1"){
        dealFindPwdStep1(jsonObj["id"].toString());
    }
    else if(tag == "findPwdStep2"){
        dealFindPwdStep2(jsonObj["id"].toString(),jsonObj["safeA"].toString());
    }
    else if(tag == "findPwdStep3"){
        dealFindPwdStep3(jsonObj["id"].toString(),jsonObj["pwd"].toString());
    }
    else if(tag == "myInfo"){
        dealMyInfo();
    }
    else if(tag == "friendInfo"){
        dealFriendInfo();
    }
    else if(tag == "deleteAccount"){
        dealDeleteAccount();
    }
    else if(tag == "outOfLogin"){
        dealOutOfLogin();
    }
    else if(tag == "searchFriendInfo"){
        dealSearchFriendInfo(jsonObj["id"].toString());
    }
    else if(tag == "addFriendRequest"){
        dealAddFriendRequest(jsonObj["id"].toString());
    }
    else if(tag == "addFriendAnswer"){
        dealAddFriendAnswer(jsonObj);
    }
    else if(tag == "deleteAFriend"){
        dealDeleteAFriend(jsonObj["friend_id"].toString());
    }
    else if(tag == "friendRequestList"){
        dealFriendRequestList();
    }
    else if(tag == "myUnReadMsg"){
        dealMyUnReadMsg();
    }
    else if(tag == "updateMyInfo"){
        dealUpdateMyInfo(jsonObj);
    }
}

void ClientHandler::onYouAreDelete(QString id)
{
    // 通知自己的客户端，这个好友已经被删除了
    QJsonObject jsonObj;
    jsonObj["tag"] = "youAreDelete";
    jsonObj["id"] = id;
    sendJsonToClient(jsonObj);
}

void ClientHandler::onFriendChangeInfo(QString id)
{
    QSqlQuery query(m_db);
    query.prepare("select id,nickname,signature,gender,avatar from Users where id = :id");
    query.bindValue(":id",id);// 每次循环更新绑定的id值
    if(query.exec() && query.next()){
        QJsonObject jsonObj;
        jsonObj["tag"] = "updateAFriendInfo";
        jsonObj["id"] = query.value(0).toString();
        jsonObj["nickname"] = query.value(1).toString();
        jsonObj["signature"] = query.value(2).toString();
        jsonObj["gender"] = query.value(3).toString();
        jsonObj["avatar"] = query.value(4).toString();
        sendJsonToClient(jsonObj);
    }
}

void ClientHandler::receiveANewMsg(QString sender, QString type, QString text, QString filename)
{
    QMutexLocker locker(&m_mutex);//确保线程安全，因为不是通过信号槽进行的
    QJsonObject jsonObj;
    jsonObj["tag"] = "msg";
    jsonObj["sender"] = sender;
    jsonObj["type"] = type;
    jsonObj["text"] = text;
    jsonObj["filename"] = filename;
    sendJsonToClient(jsonObj);
}
